﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.Data.Json;
using Windows.Storage;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

// 此文件定义的数据模型可充当在添加、移除或修改成员时
// 。  所选属性名称与标准项模板中的数据绑定一致。
//
// 应用程序可以使用此模型作为起始点并以它为基础构建，或完全放弃它并
// 替换为适合其需求的其他内容。如果使用此模式，则可提高应用程序
// 响应速度，途径是首次启动应用程序时启动 App.xaml 隐藏代码中的数据加载任务
//。

namespace yuanna.Data
{
    /// <summary>
    /// 泛型项数据模型。
    /// </summary>
    public class YuannaPoint
    {
        public YuannaPoint(String uniqueId, String longitude, String latitude, String speed, String createTime)
        {
            this.UniqueId = uniqueId;
            this.Longitude = longitude;
            this.Latitude = latitude;
            this.Speed = speed;
            this.CreateTime = createTime;
        }

        public string UniqueId { get; private set; }
        public string Longitude { get; private set; }
        public string Latitude { get; private set; }
        public string Speed { get; private set; }
        public string CreateTime { get; private set; }
    }

    /// <summary>
    /// 泛型组数据模型。
    /// </summary>
    public class YuannaPath
    {
        public YuannaPath(string uniqueId, double distance, double speed, string duration, bool isDelete, string createTime)
        {
            this.UniqueId = uniqueId;
            this.Distance = distance;
            this.Speed = speed;
            this.Duration = duration;
            this.IsDelete = isDelete;
            this.CreateTime = createTime;
            this.YuannaPoints = new ObservableCollection<YuannaPoint>();
        }

        public string UniqueId { get; private set; }
        public double Distance { get; private set; }
        public double Speed { get; private set; }
        public string Duration { get; private set; }

        public bool IsDelete { get; private set; }

        public string CreateTime { get; private set; }

        /// <summary>
        /// 跑步热量（kcal）＝体重（kg）×距离（公里）×1.036
        /// </summary>
        public double Calorie
        {
            get
            {
                var weight = 65; // 默认为65KG
                return weight * Distance * 1.036;
            }
        }

        /// <summary>
        /// 计算平均速度
        /// </summary>
        public void GetAverageSpeed()
        {
            TimeSpan time = TimeSpan.Zero;
            TimeSpan.TryParse(Duration, out time);
            var totalHours = time.TotalHours;
            if (totalHours == 0)
            {
                Speed = 0;
            }
            else
            {
                Speed = Distance / TimeSpan.Parse(Duration).TotalHours;
            }
        }

        public ObservableCollection<YuannaPoint> YuannaPoints { get; private set; }
    }

    public class YuannaData
    {
        public YuannaData()
        {
            this.YuannaPaths = new ObservableCollection<YuannaPath>();
        }

        public ObservableCollection<YuannaPath> YuannaPaths { get; private set; }
    }

    /// <summary>
    /// 创建包含从静态 json 文件读取内容的组和项的集合。
    /// 
    /// SampleDataSource 通过从项目中包括的静态 json 文件读取的数据进行
    /// 初始化。 这样在设计时和运行时均可提供示例数据。
    /// </summary>
    public sealed class YuannaDataSource
    {
        private static YuannaDataSource _yuannaDataSource = new YuannaDataSource();

        private YuannaData _yuannaData = new YuannaData();
        public YuannaData YuannaData
        {
            get { return this._yuannaData; }
        }

        public static async Task<YuannaData> GetYuannaDataAsync()
        {
            await _yuannaDataSource.GetYuannaDataFromJsonAsync();

            return _yuannaDataSource.YuannaData;
        }

        public static async Task<YuannaPath> GetYuannaPathAsync(string uniqueId)
        {
            await _yuannaDataSource.GetYuannaDataFromJsonAsync();
            // 对于小型数据集可接受简单线性搜索
            var matches = _yuannaDataSource.YuannaData.YuannaPaths.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static async Task<YuannaPoint> GetYuannaPointAsync(string uniqueId)
        {
            await _yuannaDataSource.GetYuannaDataFromJsonAsync();
            // 对于小型数据集可接受简单线性搜索
            var matches = _yuannaDataSource.YuannaData.YuannaPaths.SelectMany(group => group.YuannaPoints).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        private async Task GetYuannaDataFromJsonAsync()
        {
            if (this._yuannaData.YuannaPaths.Count != 0)
                return;

            Uri dataUri = new Uri("ms-appx:///DataModel/YuannaData.json");

            StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri);
            string jsonText = await FileIO.ReadTextAsync(file);
            JsonObject jsonObject = JsonObject.Parse(jsonText);
            JsonObject jsonObjectYuannaData = jsonObject["YuannaData"].GetObject();
            JsonArray jsonArray = jsonObjectYuannaData["YuannaPaths"].GetArray();

            foreach (JsonValue pathValue in jsonArray)
            {
                JsonObject pathObject = pathValue.GetObject();
                YuannaPath path = new YuannaPath(pathObject["UniqueId"].GetString(),
                                                            pathObject["Distance"].GetNumber(),
                                                            pathObject["Speed"].GetNumber(),
                                                            pathObject["Duration"].GetString(),
                                                            pathObject["IsDelete"].GetBoolean(),
                                                            pathObject["CreateTime"].GetString());

                foreach (JsonValue pointValue in pathObject["YuannaPoints"].GetArray())
                {
                    JsonObject pointObject = pointValue.GetObject();
                    path.YuannaPoints.Add(new YuannaPoint(pointObject["UniqueId"].GetString(),
                                                       pointObject["Longitude"].GetString(),
                                                       pointObject["Latitude"].GetString(),
                                                       pointObject["Speed"].GetString(),
                                                       pointObject["CreateTime"].GetString()));
                }
                this.YuannaData.YuannaPaths.Add(path);
            }
        }

        private async Task SaveYuannaDataToJsonFileAsync()
        {
            Uri dataUri = new Uri("ms-appx:///DataModel/YuannaData.json");
            StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri);
        }
    }
}